package com.mck.global;

import com.mck.entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.binding.BindingException;
import org.apache.ibatis.exceptions.PersistenceException;
import org.mybatis.spring.MyBatisSystemException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.sql.SQLException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @version 1.0.0
 * @Author mck
 * @Date 2025/2/23 下午11:51
 * @注释
 */

@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    // 处理数据库异常（MyBatis/SQL）
    @ExceptionHandler({PersistenceException.class, MyBatisSystemException.class})
    public ResponseEntity<Result> handleDatabaseException(RuntimeException e) {
        log.error("数据库操作异常: ", e);
        String errorMsg = extractErrorMessage(e); // 统一调用错误解析方法
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(Result.error(errorMsg));
    }

    // 处理其他所有未捕获的异常
    @ExceptionHandler(Exception.class)
    public ResponseEntity<Result> handleException(Exception e) {
        log.error("系统未知异常: ", e);
        String errorMsg = extractErrorMessage(e); // 调用错误解析方法
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(Result.error(errorMsg));
    }

    // 提取错误核心信息（含唯一约束处理）
    private String extractErrorMessage(Exception e) {
        Throwable rootCause = getRootCause(e);
        if (rootCause instanceof SQLException) {
            String msg = rootCause.getMessage();
            if (msg != null && msg.contains("Duplicate entry")) {
                // 使用正则精确提取重复值（如：'test@qq.com'）
                Pattern pattern = Pattern.compile("Duplicate entry '(.*?)' for key");
                Matcher matcher = pattern.matcher(msg);
                if (matcher.find()) {
                    String duplicateValue = matcher.group(1);
                    return "数据重复: '" + duplicateValue + "' 已存在";
                }
            }
        } else if (rootCause instanceof BindingException) {
            return "参数绑定错误: " + rootCause.getMessage();
        }
        return "操作失败: " + rootCause.getMessage();
    }

    // 递归获取根因异常
    private Throwable getRootCause(Throwable e) {
        while (e.getCause() != null && e.getCause() != e) {
            e = e.getCause();
        }
        return e;
    }
}